/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
 *
 */

import { TaskDetails, TaskInputValue } from '@ohos/hvigor';
import fse from 'fs-extra';
import path from 'path';

import { BuildArtifactConst } from '../const/build-directory-const.js';
import { OhosLogger } from '../utils/log/ohos-logger.js';

import { TargetTaskService } from './service/target-task-service.js';
import { OhosHapTask } from './task/ohos-hap-task.js';

/**
 * 生成loader需要的json文件
 *
 * @since 2022/9/9
 */
export abstract class AbstractGenerateLoaderJson extends OhosHapTask {
  protected _log: OhosLogger = OhosLogger.getLogger(AbstractGenerateLoaderJson.name);
  protected readonly workerConfig: string[] | undefined;
  protected modulePathMap: Record<string, string>;
  protected readonly projectRootPath: string;

  protected constructor(taskService: TargetTaskService, taskDetails: TaskDetails) {
    super(taskService, taskDetails);
    this.workerConfig = this.getWorkerConfig();
    this.modulePathMap = this.getModulePathMap();

    // 支持跨项目引用模块后，项目根路径要以模块的所属项目为准
    this.projectRootPath = this.service.getModuleModel().getBelongProjectPath();
  }

  declareInputs(): Map<string, TaskInputValue> {
    const map = new Map<string, TaskInputValue>().set('projectRootPath', this.projectRootPath).set('modulePathMap', JSON.stringify(this.modulePathMap));
    if (this.workerConfig !== undefined) {
      map.set('workerConfig', JSON.stringify(this.workerConfig));
    }
    return map;
  }

  protected beforeTask() {
    // clean output
    const loaderJsonPath: string = path.resolve(this.targetData.getPathInfo().getIntermediatesLoaderPath(), BuildArtifactConst.LOADER_JSON);
    if (fse.existsSync(loaderJsonPath)) {
      fse.removeSync(loaderJsonPath);
    }
  }

  protected getWorkerConfig(): string[] | undefined {
    const workerConfig = this.targetService.getWorkerConfig();
    return workerConfig.length === 0 ? undefined : workerConfig;
  }

  private getModulePathMap(): Record<string, string> {
    const modulePathMap: Record<string, string> = {};

    this.projectModel
      .getProject()
      .getSubModules()!
      .forEach((subModule, moduleName) => {
        modulePathMap[moduleName] = subModule.getNodeDir();
      });
    return modulePathMap;
  }
}
